home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1997 February / EnigmA AMIGA RUN 15 (1997)(G.R. Edizioni)(IT)[!][issue 1997-02][PLANET CD V].iso / enigma / earcd / varie / uae-0_64.lha / uae-0.6.4 / src / dos-dma.c < prev    next >
C/C++ Source or Header  |  1996-08-14  |  3KB  |  103 lines

  1.  /*
  2.   * UAE - The Un*x Amiga Emulator
  3.   *
  4.   * DOS DMA interface.
  5.   *
  6.   * (c) 1996 Peter Remmers
  7.   */
  8.  
  9. #include <stdlib.h>
  10. #include <pc.h>
  11. #include <dpmi.h>
  12.  
  13. #include "dos-dma.h"
  14.  
  15. /* some useful macros */
  16. #define LOBYTE(x) ((unsigned char)(((unsigned short)(x)) &  0xFF))
  17. #define HIBYTE(x) ((unsigned char)(((unsigned short)(x)) >> 8))
  18. #define LOWORD(x) ((unsigned short)(((unsigned long)(x)) & 0xFFFF))
  19. #define HIWORD(x) ((unsigned short)(((unsigned long)(x)) >> 16))
  20.  
  21. const unsigned short DMA_Address [8] = {0x00,0x02,0x04,0x06,0xC0,0xC4,0xC8,0xCC};
  22. const unsigned short DMA_Count   [8] = {0x01,0x03,0x05,0x07,0xC2,0xC6,0xCA,0xCE};
  23.  
  24. const unsigned short DMA_PageLo[8]= { 0x87, 0x83, 0x81, 0x82, 0x8F, 0x8B, 0x89, 0x8A};
  25. const unsigned short DMA_PageHi[8]= {0x487,0x483,0x481,0x482,0x48F,0x48B,0x489,0x48A};
  26.  
  27. #define DMA_Status(ch)        ((ch)<4 ? 0x08 : 0xD0)  /* Read  */
  28. #define DMA_Command(ch)       ((ch)<4 ? 0x08 : 0xD0)  /* Write */
  29. #define DMA_Request(ch)       ((ch)<4 ? 0x09 : 0xD2)
  30. #define DMA_MaskSingle(ch)    ((ch)<4 ? 0x0A : 0xD4)
  31. #define DMA_Mode(ch)          ((ch)<4 ? 0x0B : 0xD6)
  32. #define DMA_ClearFF(ch)       ((ch)<4 ? 0x0C : 0xD8)
  33. #define DMA_Latch(ch)         ((ch)<4 ? 0x0D : 0xDA)  /* Read  */
  34. #define DMA_MasterClear(ch)   ((ch)<4 ? 0x0D : 0xDA)  /* Write */
  35. #define DMA_ClearMask(ch)     ((ch)<4 ? 0x0E : 0xDC)
  36. #define DMA_MaskAll(ch)       ((ch)<4 ? 0x0F : 0xDE)
  37.  
  38.  
  39. /* allocate DOS memory that does not cross a physical 64k boundary */
  40. unsigned long DMA_AllocDMABuf  (_go32_dpmi_seginfo *info)
  41. {
  42.   unsigned long Phys;
  43.   unsigned long bytes;
  44.  
  45.   /* first allocate requested size */
  46.   if (_go32_dpmi_allocate_dos_memory (info)) return (NULL);
  47.  
  48.   Phys  = (info->rm_segment) << 4;
  49.   bytes = (info->size)       << 4;
  50.   
  51.   /* if memory does not cross boundary we are lucky and that's it */
  52.   if (HIWORD(Phys + bytes) == HIWORD (Phys)) return (Phys);
  53.  
  54.   /* if not, free memory */
  55.   _go32_dpmi_free_dos_memory (info);
  56.  
  57.   /* and allocate twice the requested size */
  58.   bytes      <<= 1;
  59.   info->size <<= 1;
  60.   if (_go32_dpmi_allocate_dos_memory (info)) return (NULL);
  61.  
  62.   /* and take the half that does not cross a boundary */
  63.   Phys = (info->rm_segment) << 4;
  64.   if (HIWORD(Phys + bytes) == HIWORD (Phys)) return (Phys);
  65.   
  66.   return (Phys + (bytes>>1));
  67. }
  68.  
  69. void DMA_Mask (unsigned char channel)
  70. {
  71.   outportb(DMA_MaskSingle(channel), 4 + (channel&3));
  72. }
  73.  
  74. void DMA_UnMask (unsigned char channel)
  75. {
  76.   outportb(DMA_MaskSingle(channel), channel&3);
  77. }
  78.  
  79. void DMA_InitTransfer (unsigned char channel, unsigned char Mode,
  80.                        unsigned long PhysAddr, unsigned short Count)
  81. {
  82.   unsigned short Page;
  83.   unsigned short Addr;
  84.  
  85.   if (channel & 4) Count >>= 1;
  86.   Count--;
  87.   
  88.   Page = HIWORD(PhysAddr);
  89.   if (channel & 4) PhysAddr >>= 1;
  90.   Addr = LOWORD (PhysAddr);
  91.  
  92.   outportb (DMA_MaskSingle(channel), (channel&3) + 0x04);
  93.   outportb (DMA_Mode      (channel), (channel&3) | (Mode&0xFC));
  94.   outportb (DMA_ClearFF   (channel), 0);
  95.   outportb (DMA_Count     [channel], LOBYTE(Count));
  96.   outportb (DMA_Count     [channel], HIBYTE(Count));
  97.   outportb (DMA_Address   [channel], LOBYTE(Addr));
  98.   outportb (DMA_Address   [channel], HIBYTE(Addr));
  99.   outportb (DMA_PageLo    [channel], LOBYTE(Page));
  100.   outportb (DMA_PageHi    [channel], HIBYTE(Page));
  101.   outportb (DMA_MaskSingle(channel), channel&3);
  102. }
  103.